{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "39fd1948-b5c3-48c4-b10e-2ae7e8c83334",
   "metadata": {},
   "source": [
    "# Basic Multi-agent Collaboration\n",
    "\n",
    "A single agent can usually operate effectively using a handful of tools within a single domain, but even using powerful models like `gpt-4`, it can be less effective at using many tools. \n",
    "\n",
    "One way to approach complicated tasks is through a \"divide-and-conquer\" approach: create an specialized agent for each task or domain and route tasks to the correct \"expert\".\n",
    "\n",
    "This notebook (inspired by the paper [AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation](https://arxiv.org/abs/2308.08155), by Wu, et. al.) shows one way to do this using LangGraph.\n",
    "\n",
    "The resulting graph will look something like the following diagram:\n",
    "\n",
    "![multi_agent diagram](./img/simple_multi_agent_diagram.png)\n",
    "\n",
    "Before we get started, a quick note: this and other multi-agent notebooks are designed to show _how_ you can implement certain design patterns in LangGraph. If the pattern suits your needs, we recommend combining it with some of the other fundamental patterns described elsewhere in the docs for best performance."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "0d7b6dcc-c985-46e2-8457-7e6b0298b950",
   "metadata": {},
   "outputs": [],
   "source": [
    "# %pip install -U langchain langchain_openai langsmith pandas langchain_experimental matplotlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "743c19df-6da9-4d1e-b2d2-ea40080b9fdc",
   "metadata": {},
   "outputs": [],
   "source": [
    "import getpass\n",
    "import os\n",
    "\n",
    "\n",
    "def _set_if_undefined(var: str):\n",
    "    if not os.environ.get(var):\n",
    "        os.environ[var] = getpass(f\"Please provide your {var}\")\n",
    "\n",
    "\n",
    "_set_if_undefined(\"OPENAI_API_KEY\")\n",
    "_set_if_undefined(\"LANGCHAIN_API_KEY\")\n",
    "_set_if_undefined(\"TAVILY_API_KEY\")\n",
    "\n",
    "# Optional, add tracing in LangSmith\n",
    "os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
    "os.environ[\"LANGCHAIN_PROJECT\"] = \"Multi-agent Collaboration\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "075c91c3-c249-471d-b259-41975faa83fb",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "5e4344a7-21df-4d54-90d2-9d19b3416ffb",
   "metadata": {},
   "source": [
    "## Create Agents\n",
    "\n",
    "The following helper functions will help create agents. These agents will then be nodes in the graph.\n",
    "\n",
    "You can skip ahead if you just want to see what the graph looks like."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "4325a10e-38dc-4a98-9004-e1525eaba377",
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "\n",
    "from langchain_core.messages import (\n",
    "    AIMessage,\n",
    "    BaseMessage,\n",
    "    ChatMessage,\n",
    "    FunctionMessage,\n",
    "    HumanMessage,\n",
    ")\n",
    "from langchain.tools.render import format_tool_to_openai_function\n",
    "from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
    "from langgraph.graph import END, StateGraph\n",
    "from langgraph.prebuilt.tool_executor import ToolExecutor, ToolInvocation\n",
    "\n",
    "\n",
    "def create_agent(llm, tools, system_message: str):\n",
    "    \"\"\"Create an agent.\"\"\"\n",
    "    functions = [format_tool_to_openai_function(t) for t in tools]\n",
    "\n",
    "    prompt = ChatPromptTemplate.from_messages(\n",
    "        [\n",
    "            (\n",
    "                \"system\",\n",
    "                \"You are a helpful AI assistant, collaborating with other assistants.\"\n",
    "                \" Use the provided tools to progress towards answering the question.\"\n",
    "                \" If you are unable to fully answer, that's OK, another assistant with different tools \"\n",
    "                \" will help where you left off. Execute what you can to make progress.\"\n",
    "                \" If you or any of the other assistants have the final answer or deliverable,\"\n",
    "                \" prefix your response with FINAL ANSWER so the team knows to stop.\"\n",
    "                \" You have access to the following tools: {tool_names}.\\n{system_message}\",\n",
    "            ),\n",
    "            MessagesPlaceholder(variable_name=\"messages\"),\n",
    "        ]\n",
    "    )\n",
    "    prompt = prompt.partial(system_message=system_message)\n",
    "    prompt = prompt.partial(tool_names=\", \".join([tool.name for tool in tools]))\n",
    "    return prompt | llm.bind_functions(functions)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b4b40de2-5dd4-4d5b-882e-577210723ff4",
   "metadata": {},
   "source": [
    "## Define tools\n",
    "\n",
    "We will also define some tools that our agents will use in the future"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "ca076f3b-a729-4ca9-8f91-05c2ba58d610",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_core.tools import tool\n",
    "from typing import Annotated\n",
    "from langchain_experimental.utilities import PythonREPL\n",
    "from langchain_community.tools.tavily_search import TavilySearchResults\n",
    "\n",
    "tavily_tool = TavilySearchResults(max_results=5)\n",
    "\n",
    "# Warning: This executes code locally, which can be unsafe when not sandboxed\n",
    "\n",
    "repl = PythonREPL()\n",
    "\n",
    "\n",
    "@tool\n",
    "def python_repl(\n",
    "    code: Annotated[str, \"The python code to execute to generate your chart.\"]\n",
    "):\n",
    "    \"\"\"Use this to execute python code. If you want to see the output of a value,\n",
    "    you should print it out with `print(...)`. This is visible to the user.\"\"\"\n",
    "    try:\n",
    "        result = repl.run(code)\n",
    "    except BaseException as e:\n",
    "        return f\"Failed to execute. Error: {repr(e)}\"\n",
    "    return f\"Succesfully executed:\\n```python\\n{code}\\n```\\nStdout: {result}\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f1b54c0c-0b09-408b-abc5-86308929afb6",
   "metadata": {},
   "source": [
    "## Create graph\n",
    "\n",
    "Now that we've defined our tools and made some helper functions, will create the individual agents below and tell them how to talk to each other using LangGraph."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0c6a8c3c-86a0-46aa-b970-ab070fb787d9",
   "metadata": {},
   "source": [
    "### Define State\n",
    "\n",
    "We first define the state of the graph. This will just a list of messages, along with a key to track the most recent sender"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "290c91d4-f6f4-443c-8181-233d39102974",
   "metadata": {},
   "outputs": [],
   "source": [
    "import operator\n",
    "from typing import Annotated, List, Sequence, Tuple, TypedDict, Union\n",
    "\n",
    "from langchain.agents import create_openai_functions_agent\n",
    "from langchain.tools.render import format_tool_to_openai_function\n",
    "from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
    "\n",
    "from langchain_openai import ChatOpenAI\n",
    "from typing_extensions import TypedDict\n",
    "\n",
    "\n",
    "# This defines the object that is passed between each node\n",
    "# in the graph. We will create different nodes for each agent and tool\n",
    "class AgentState(TypedDict):\n",
    "    messages: Annotated[Sequence[BaseMessage], operator.add]\n",
    "    sender: str"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "911a283e-ea04-40c1-b792-f9e5f7d81203",
   "metadata": {},
   "source": [
    "### Define Agent Nodes\n",
    "\n",
    "We now need to define the nodes. First, let's define the nodes for the agents."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "71b790ca-9cef-4b22-b469-4b1d5d8424d6",
   "metadata": {},
   "outputs": [],
   "source": [
    "import functools\n",
    "\n",
    "\n",
    "# Helper function to create a node for a given agent\n",
    "def agent_node(state, agent, name):\n",
    "    result = agent.invoke(state)\n",
    "    # We convert the agent output into a format that is suitable to append to the global state\n",
    "    if isinstance(result, FunctionMessage):\n",
    "        pass\n",
    "    else:\n",
    "        result = HumanMessage(**result.dict(exclude={\"type\", \"name\"}), name=name)\n",
    "    return {\n",
    "        \"messages\": [result],\n",
    "        # Since we have a strict workflow, we can\n",
    "        # track the sender so we know who to pass to next.\n",
    "        \"sender\": name,\n",
    "    }\n",
    "\n",
    "\n",
    "llm = ChatOpenAI(model=\"gpt-4-1106-preview\")\n",
    "\n",
    "# Research agent and node\n",
    "research_agent = create_agent(\n",
    "    llm,\n",
    "    [tavily_tool],\n",
    "    system_message=\"You should provide accurate data for the chart generator to use.\",\n",
    ")\n",
    "research_node = functools.partial(agent_node, agent=research_agent, name=\"Researcher\")\n",
    "\n",
    "# Chart Generator\n",
    "chart_agent = create_agent(\n",
    "    llm,\n",
    "    [python_repl],\n",
    "    system_message=\"Any charts you display will be visible by the user.\",\n",
    ")\n",
    "chart_node = functools.partial(agent_node, agent=chart_agent, name=\"Chart Generator\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "71c7f1b2-24a3-4340-bcb2-feb22e344fb6",
   "metadata": {},
   "source": [
    "### Define Tool Node\n",
    "\n",
    "We now define a node to run the tools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "d9a79c76-5c7c-42f6-91cf-635bc8305804",
   "metadata": {},
   "outputs": [],
   "source": [
    "tools = [tavily_tool, python_repl]\n",
    "tool_executor = ToolExecutor(tools)\n",
    "\n",
    "\n",
    "def tool_node(state):\n",
    "    \"\"\"This runs tools in the graph\n",
    "\n",
    "    It takes in an agent action and calls that tool and returns the result.\"\"\"\n",
    "    messages = state[\"messages\"]\n",
    "    # Based on the continue condition\n",
    "    # we know the last message involves a function call\n",
    "    last_message = messages[-1]\n",
    "    # We construct an ToolInvocation from the function_call\n",
    "    tool_input = json.loads(\n",
    "        last_message.additional_kwargs[\"function_call\"][\"arguments\"]\n",
    "    )\n",
    "    # We can pass single-arg inputs by value\n",
    "    if len(tool_input) == 1 and \"__arg1\" in tool_input:\n",
    "        tool_input = next(iter(tool_input.values()))\n",
    "    tool_name = last_message.additional_kwargs[\"function_call\"][\"name\"]\n",
    "    action = ToolInvocation(\n",
    "        tool=tool_name,\n",
    "        tool_input=tool_input,\n",
    "    )\n",
    "    # We call the tool_executor and get back a response\n",
    "    response = tool_executor.invoke(action)\n",
    "    # We use the response to create a FunctionMessage\n",
    "    function_message = FunctionMessage(\n",
    "        content=f\"{tool_name} response: {str(response)}\", name=action.tool\n",
    "    )\n",
    "    # We return a list, because this will get added to the existing list\n",
    "    return {\"messages\": [function_message]}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bcb30498-dbc4-4b20-980f-da08ebc9da56",
   "metadata": {},
   "source": [
    "### Define Edge Logic\n",
    "\n",
    "We can define some of the edge logic that is needed to decide what to do based on results of the agents"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "4f4b4d37-e8a3-4abb-8d42-eaea26016f35",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Either agent can decide to end\n",
    "def router(state):\n",
    "    # This is the router\n",
    "    messages = state[\"messages\"]\n",
    "    last_message = messages[-1]\n",
    "    if \"function_call\" in last_message.additional_kwargs:\n",
    "        # The previus agent is invoking a tool\n",
    "        return \"call_tool\"\n",
    "    if \"FINAL ANSWER\" in last_message.content:\n",
    "        # Any agent decided the work is done\n",
    "        return \"end\"\n",
    "    return \"continue\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e9359c34-e191-43a2-a3d4-f2dea636dfd2",
   "metadata": {},
   "source": [
    "### Define the Graph\n",
    "\n",
    "We can now put it all together and define the graph!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "4dce3901-6ad5-4df5-8528-6e865cf96cb0",
   "metadata": {},
   "outputs": [],
   "source": [
    "workflow = StateGraph(AgentState)\n",
    "\n",
    "workflow.add_node(\"Researcher\", research_node)\n",
    "workflow.add_node(\"Chart Generator\", chart_node)\n",
    "workflow.add_node(\"call_tool\", tool_node)\n",
    "\n",
    "workflow.add_conditional_edges(\n",
    "    \"Researcher\",\n",
    "    router,\n",
    "    {\"continue\": \"Chart Generator\", \"call_tool\": \"call_tool\", \"end\": END},\n",
    ")\n",
    "workflow.add_conditional_edges(\n",
    "    \"Chart Generator\",\n",
    "    router,\n",
    "    {\"continue\": \"Researcher\", \"call_tool\": \"call_tool\", \"end\": END},\n",
    ")\n",
    "\n",
    "workflow.add_conditional_edges(\n",
    "    \"call_tool\",\n",
    "    # Each agent node updates the 'sender' field\n",
    "    # the tool calling node does not, meaning\n",
    "    # this edge will route back to the original agent\n",
    "    # who invoked the tool\n",
    "    lambda x: x[\"sender\"],\n",
    "    {\n",
    "        \"Researcher\": \"Researcher\",\n",
    "        \"Chart Generator\": \"Chart Generator\",\n",
    "    },\n",
    ")\n",
    "workflow.set_entry_point(\"Researcher\")\n",
    "graph = workflow.compile()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8c9447e7-9ab6-43eb-8ae6-9b52f8ba8425",
   "metadata": {},
   "source": [
    "## Invoke\n",
    "\n",
    "With the graph created, you can invoke it! Let's have it chart some stats for us."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "176a99b0-b457-45cf-8901-90facaa852da",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'Researcher': {'messages': [HumanMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"UK GDP data for the past 5 years\"}', 'name': 'tavily_search_results_json'}}, name='Researcher')], 'sender': 'Researcher'}}\n",
      "----\n",
      "{'call_tool': {'messages': [FunctionMessage(content=\"tavily_search_results_json response: [{'url': 'https://www.statista.com/topics/3795/gdp-of-the-uk/', 'content': 'Monthly GDP of the UK 2019-2023  Monthly GDP growth of the UK 2019-2023  Quarterly GDP growth of the UK 2019-2023  Quarterly GDP per capita in the UK 2019-2023Monthly index of gross domestic product in the United Kingdom from January 2019 to November 2023 (2019=100) GVA of the UK 2022, by sector GVA of the UK 2022, by sector Gross value added...'}, {'url': 'https://www.statista.com/topics/6500/the-british-economy/', 'content': 'Monthly GDP growth of the UK 2020-2023  Quarterly GDP growth of the UK 2015-2023  Monthly growth of gross domestic product in the United Kingdom from January 2020 to September 2023  Monthly GDP of the UK 1997-2023Economy The UK economy - Statistics & Facts United Kingdom The gross domestic product of the British economy was 2.23 trillion British pounds in 2022 and was the fifth- largest global...'}, {'url': 'https://www.ons.gov.uk/economy/grossdomesticproductgdp/bulletins/gdpmonthlyestimateuk/november2023', 'content': 'data from January 2022 to September 2023, as published in our\\\\xa0GDP quarterly national accounts, UK: July to September  Figure 1: UK GDP is estimated to have grown by 0.3% in November 2023  GDP monthly estimate, UK: November 2023  Source: Monthly GDP estimate from Office for National Statistics The main reasons for revisions in October 2023 are:Monthly GDP is estimated to have grown by 0.3% in November 2023, following an unrevised fall of 0.3% in October 2023. This release provides data for November 2023 and has revisions from January 2022 to September 2023, consistent with our Quarterly national accounts bulletin, published on 22 December 2023. October 2023 is also open for revision.'}, {'url': 'https://www.statista.com/statistics/375195/gdp-growth-forecast-uk/', 'content': 'Forecasted annual growth of gross domestic product in the United Kingdom from 2000 to 2028 Additional Information  GDP growth forecast for the UK 2000-2028 Weak economic growth throughout 2023  United Kingdom 2000 to 2028 *Forecast data Other statistics on the topicThe UK economy Economy  Economy Average annual earnings for full-time employees in the UK 1999-2023 Economy Inflation rate in the UK 1989-2023In 2022 the gross domestic product (GDP) of the United Kingdom grew by four percent but is expected to grow by just 0.6 percent in 2023, and 0.7 percent in 2024. More robust growth is...'}, {'url': 'https://www.ons.gov.uk/economy/grossdomesticproductgdp/bulletins/gdpmonthlyestimateuk/october2023', 'content': 'GDP monthly estimate, UK: October 2023  Figure 1: UK GDP is estimated to have fallen by 0.3% in October 2023  Monthly estimate of gross domestic product (GDP) containing constant price gross value added (GVA) data for the UK.  domestic product (GDP) in October 2023.1. Main points Monthly real gross domestic product (GDP) is estimated to have shown no growth in the three months to October 2023, compared with the three months to July 2023. Monthly GDP...'}]\", name='tavily_search_results_json')]}}\n",
      "----\n",
      "{'Researcher': {'messages': [HumanMessage(content=\"The search results provide information on the UK's GDP, including monthly and quarterly data from various years, but they do not provide a clear year-on-year GDP figure for each of the past five years. To graph the UK's GDP over the past five years, we need annual GDP figures for each year.\\n\\nI will attempt to extract the annual GDP figures mentioned in the search results and then graph them. However, please note that the information provided in the search results may be incomplete or not formatted in a way that allows for a straightforward extraction of annual GDP figures for each of the last five years. If necessary, I may need to perform additional searches to fill in any gaps.\\n\\nFrom the search results, we have the following relevant information regarding the UK's GDP:\\n\\n- The gross domestic product of the British economy was 2.23 trillion British pounds in 2022.\\n- In 2022, the gross domestic product (GDP) of the United Kingdom grew by four percent.\\n\\nUnfortunately, the search results do not provide explicit annual GDP figures for 2018, 2019, 2020, or 2021. Therefore, I will need to perform an additional search to find the missing GDP figures for these years. Let's proceed with that search.\", additional_kwargs={'function_call': {'arguments': '{\"query\":\"UK GDP 2018 2019 2020 2021\"}', 'name': 'tavily_search_results_json'}}, name='Researcher')], 'sender': 'Researcher'}}\n",
      "----\n",
      "{'call_tool': {'messages': [FunctionMessage(content='tavily_search_results_json response: [{\\'url\\': \\'https://www.statista.com/topics/3795/gdp-of-the-uk/\\', \\'content\\': \"GDP of the UK 2021, by country Gross domestic product of the United Kingdom in 2021, by country (in million GBP)  Monthly GDP of the UK 2019-2023  United Kingdom\\'s share of global gross domestic product (GDP) 2028  Quarterly GDP per capita in the UK 2019-2023In 2022, the gross domestic product of the United Kingdom amounted to approximately 2.2 trillion British pounds, compared with 2.14 trillion pounds in 2021, and 1.99 trillion in 2020. Although the ...\"}, {\\'url\\': \\'https://www.beta.ons.gov.uk/economy/grossdomesticproductgdp/compendium/unitedkingdomnationalaccountsthebluebook/2022/nationalaccountsataglance\\', \\'content\\': \"of UK GDP over 2020 and 2021  Figure 1: The UK economy increased by 7.5% in 2021, having seen the largest fall in over 300 years in 2020  accounts at a glance, UK National Accounts, The Blue Book: 2022  Figure 3: In 2021, nominal GDP in most of the G20 countries had recovered to its 2019 levelsIn 2021, the UK\\'s implied GDP deflator rose by 0.4%, the lowest among the developed countries shown (Figure 4). However, these comparisons are likely to reflect some of the measurement challenges over the coronavirus pandemic. Movements in the implied GDP deflator in 2020 and 2021 have been largely affected by the government consumption deflator.\"}, {\\'url\\': \\'https://www.ons.gov.uk/economy/grossdomesticproductgdp/bulletins/gdpmonthlyestimateuk/december2021\\', \\'content\\': \\'GDP monthly estimate, UK : December 2021  gross domestic product (GDP), UK.  data from January 2021 to November 2021. This is consistent with GDP first quarterly estimate, UK: October to December  on gross domestic product (GDP) in December 2021, with output of these services increasing by 51% and 19% respectively2. Monthly GDP. Monthly real gross domestic product (GDP) is estimated to have fallen by 0.2% in December 2021, compared with a 0.7% growth in November 2021 (revised down from 0.9% growth). This release includes revisions to the monthly data back to January 2021, consistent with the first quarterly estimate of GDP.\\'}, {\\'url\\': \\'https://www.beta.ons.gov.uk/economy/grossdomesticproductgdp/bulletins/gdpmonthlyestimateuk/september2021\\', \\'content\\': \\'GDP monthly estimate, UK: September 2021  2021, while detail on the quarterly path can also be found in GDP first quarterly estimate, UK: July to September 2021.  More detail on the quarterly path can also be found in GDP first quarterly estimate, UK: July to September 2021.  while detail on the quarterly path can also be found in GDP first quarterly estimate, UK: July to September 2021.Source: Office for National Statistics - GDP monthly estimate. Download this chart. Image .csv .xls. Monthly real gross domestic product (GDP) grew by 0.6% in September 2021, and follows a revised 0.2% growth in August 2021 (down from 0.4% growth) and a revised 0.2% fall in July 2021 (down from a 0.1% fall).\\'}, {\\'url\\': \\'https://www.ons.gov.uk/economy/grossdomesticproductgdp/bulletins/gdpmonthlyestimateuk/october2021\\', \\'content\\': \\'GDP monthly estimate, UK : October 2021  Figure 1: UK GDP is estimated to have grown by 0.1% in October 2021, but remains 0.5% below its pre-pandemic level  Monthly estimate of gross domestic product (GDP) containing constant price gross value added (GVA) data for the UK.  Source: Office for National Statistics – GDP monthly estimate NotesTable 1: UK GDP in October 2021 was 0.5% below its pre-pandemic level, however services has now returned to its pre-pandemic levelChange in output, percentage change, February 2020 to October 2021, UK. Source: Office for National Statistics - GDP monthly estimate. This table uses data from the output measure of GDP.\\'}]', name='tavily_search_results_json')]}}\n",
      "----\n",
      "{'Researcher': {'messages': [HumanMessage(content=\"Based on the search results, we can now extract some annual GDP figures for the UK:\\n\\n- In 2022, the gross domestic product of the United Kingdom amounted to approximately 2.2 trillion British pounds.\\n- In 2021, the gross domestic product of the United Kingdom was about 2.14 trillion British pounds.\\n- In 2020, the gross domestic product of the United Kingdom was about 1.99 trillion British pounds.\\n\\nUnfortunately, the search results still do not provide explicit figures for 2018 and 2019. To complete the dataset, we would need to perform another search or access historical economic data from a reliable source such as the Office for National Statistics (ONS) or an economic database. If additional searches are not possible, we may need to use these three data points to give a partial visualization of the trend. \\n\\nSince we cannot perform additional searches, I will provide the data points we have, and you will need to add the missing years' data manually if required:\\n\\n- 2020: 1.99 trillion GBP\\n- 2021: 2.14 trillion GBP\\n- 2022: 2.2 trillion GBP\\n\\nPlease note that the data for 2018 and 2019 is missing, and you would need to find these figures to complete the five-year view. With the data at hand, the line graph would only represent the years 2020 to 2022.\", name='Researcher')], 'sender': 'Researcher'}}\n",
      "----\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Python REPL can execute arbitrary code. Use with caution.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'Chart Generator': {'messages': [HumanMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"code\":\"import matplotlib.pyplot as plt\\\\n\\\\n# Define the data\\\\nyears = [2020, 2021, 2022]\\\\ngdp_values = [1.99, 2.14, 2.2] # Trillion GBP\\\\n\\\\n# Create the line graph\\\\nplt.figure(figsize=(10, 5))\\\\nplt.plot(years, gdp_values, marker=\\'o\\')\\\\n\\\\n# Labeling the graph\\\\nplt.title(\\'UK GDP from 2020 to 2022\\')\\\\nplt.xlabel(\\'Year\\')\\\\nplt.ylabel(\\'GDP (Trillion GBP)\\')\\\\nplt.grid(True)\\\\nplt.xticks(years)\\\\nplt.tight_layout()\\\\n\\\\n# Display the graph\\\\nplt.show()\"}', 'name': 'python_repl'}}, name='Chart Generator')], 'sender': 'Chart Generator'}}\n",
      "----\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAHqCAYAAAAZLi26AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABv/UlEQVR4nO3deVyVZf7/8fc57DsCAoIo4K5gWu6WtribRjbN1NSUTU0zhTOZLeaSS1bYbuWMTc20/DJr6qtmmaloroWWminuCu6CCrJvB879+8M8dRIVlMNheT0fDx55rvu67/O5j+TNm+u+r8tkGIYhAAAAAABQ48zOLgAAAAAAgIaK0A0AAAAAgIMQugEAAAAAcBBCNwAAAAAADkLoBgAAAADAQQjdAAAAAAA4CKEbAAAAAAAHIXQDAAAAAOAghG4AAAAAAByE0A0AgJOVl5frySefVFRUlMxmsxISEpxdEgAAqCGEbgBArZk2bZpMJpNOnz5d6fa4uDhdf/31ttcHDx6UyWTSyy+/bNfPMAz99a9/lclk0rRp0y75vqWlpXrzzTd17bXXqkmTJnJ3d1dERIRGjhypjz/+WBUVFee957kvNzc3hYSEqE+fPpo4caIOHz583vFXr1593j6xsbG65557lJaWdsn63n33Xb300kv63e9+pw8++ECPPvroJfdxlqKiIv3zn//UoEGD1KxZM/n5+alr166aM2eO3ed4jtVq1YsvvqiYmBh5enqqc+fO+vjjj8/r8/7772vkyJGKioqSj4+P4uLi9Oyzz6qkpKTSOv773/+qQ4cO8vT0VJs2bfTmm29Wqf7vvvtO06ZNU05OTrXP/WJWrlypP//5z2rbtq28vb0VGxurBx54QCdOnLhgHddee628vb0VHh6uf/zjHyooKLDr88MPP2jMmDHq1KmTfHx81KJFC/3+97/X3r177fpdzucHAKg9rs4uAACA6jAMQw8//LDefvttPf3005cM3adOndLQoUO1efNmDR48WJMnT1ZQUJAyMjK0YsUK/fGPf9T+/fv19NNP2+135513atiwYbJarTpz5ox++OEHzZo1S6+//rr++9//6o477jjvvf7xj3+oe/fuslgs2rJli95++2199dVX2r59uyIiIi5Y4zfffKPIyEi99tprl/WZ1Ka0tDT9/e9/10033aRx48bJ399fy5Yt08MPP6wNGzbogw8+sOs/adIkzZw5U3/5y1/UvXt3LVq0SH/84x9lMplsn2FRUZHuu+8+9erVS3/7298UGhqqlJQUTZ06VStXrtQ333wjk8lkO+a///1v/e1vf9Ntt92mcePGad26dfrHP/6hoqIijR8//qL1f/fdd5o+fbpGjx6twMDAGvtcxo8fr+zsbN1+++1q06aN0tLSNHv2bC1evFhbt25VeHi4re/WrVt10003qUOHDnr11Vd19OhRvfzyy9q3b5++/vprW78XXnhB3377rW6//XZ17txZGRkZmj17tq6++mpt2LBBcXFxl/X5AQBqmQEAQC2ZOnWqIck4depUpds7depk9O/f3/Y6PT3dkGS89NJLtrbExERDkjFp0qQqvefgwYMNs9lszJ8/v9LtP/zwgzF37tyLvuc5Bw8eNNq2bWu4u7sbW7dutbWvWrXKkGR89tlndv3feOMNQ5Lx/PPPX7TGG264wejUqdMlz8VisRilpaWX7OdIp06dMlJTU89rv++++wxJxr59+2xtR48eNdzc3IzExERbm9VqNa677jqjefPmRnl5uWEYhlFaWmp8++235x1z+vTphiQjOTnZ1lZUVGQEBwcbw4cPt+t71113GT4+PkZ2dvZF63/ppZcMSUZ6enqVzreq1qxZY1RUVJzXVtn36tChQ41mzZoZubm5trZ33nnHkGQsW7bM1vbtt9+e9/e9d+9ew8PDw7jrrrtsbdX5/AAAtY/bywEA9cYjjzyif/7zn5owYYKeffbZS/ZPSUnRsmXL9OCDD2rUqFGV9unWrZvuuuuuKr1/y5Yt9f7776usrEwvvvjiJfvfeOONkqT09PRKt5+7lX3VqlXasWOH7fb01atX291aP2vWLLVq1UoeHh7auXOnpLOj49ddd518fHwUGBioW265Rbt27bI7/rnb+ffu3au7775bAQEBatq0qZ5++mkZhqEjR47olltukb+/v8LDw/XKK69c8pxCQkLUqVOn89pvvfVWSbKrYdGiRbJYLHr44YdtbSaTSQ899JCOHj2qlJQUSZK7u7v69OlTpWOuWrVKWVlZdseUpMTERBUWFuqrr766YO3Tpk3TE088IUmKiYmxfd4HDx6UdPbZ+hkzZtg+6+joaE2cOFGlpaUX/UwkqV+/fjKbzee1BQUF2dWfl5en5ORk3X333fL397e133PPPfL19dWn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Tik0NFRr1qxRv379lJubq6ZNm2revHn63e9+J0navXu3OnTooJSUFPXq1avS4yQmJmrXrl365ptvJEnjx4/XV199pdTUVFufO+64Qzk5OVq6dKnjTwwAUOc46prza9dff726dOmiWbNmOfJUAAD1QG1cd87p1KmT/vCHP2jKlCkOOZfqYqS7DsnNzZUkBQUFSTr7mx2LxaIBAwbY+rRv314tWrRQSkrKRY9z7hiSlJKSYncMSRo8ePBFjwEAaNgcdc0BAKAytXXdsVqtys/Pr1PXJldnF4CzrFarxo4dq759+youLk6SlJGRIXd3dwUGBtr1DQsLU0ZGRqXH+e677/S///1PX331la0tIyNDYWFh5x0jLy9PxcXF8vLyqtmTAQDUaY685gAA8Fu1ed15+eWXVVBQoN///vc1Vv+VInTXEYmJiUpNTdX69esv+xipqam65ZZbNHXqVA0aNKgGqwMANCRccwAAtam2rjvz5s3T9OnTtWjRIoWGhl72e9U0bi+vA8aMGaPFixdr1apVat68ua09PDxcZWVlysnJseufmZmp8PBwu7adO3fqpptu0oMPPqjJkyfbbQsPD7ebBfDcMfz9/RnlBoBGxtHXHAAAfq22rjuffPKJHnjgAX366afnPVrrbIRuJzIMQ2PGjNHChQv1zTffKCYmxm77NddcIzc3N61cudLWtmfPHh0+fFi9e/e2te3YsUM33HCD7r33Xj333HPnvU/v3r3tjiFJycnJdscAADRstXXNAQBAqt3rzscff6z77rtPH3/8sYYPH+6YE7oCzF7uRA8//LDmzZunRYsWqV27drb2gIAA2wj0Qw89pCVLluj999+Xv7+//v73v0s6+zyDdPY2ixtvvFGDBw/WSy+9ZDuGi4uLmjZtKunskmFxcXFKTEzUn//8Z33zzTf6xz/+oa+++kqDBw+urdMFADhRbV1zJGnr1q2SpAceeEDt2rXTE088IXd3d3Xs2NHRpwkAqCNq67ozb9483XvvvXr99dftlhvz8vJSQECAw8+zSgw4jaRKv9577z1bn+LiYuPhhx82mjRpYnh7exu33nqrceLECdv2qVOnVnqMli1b2r3XqlWrjC5duhju7u5GbGys3XsAABq+2rzmVKUPAKBhq63rTv/+/Svtc++999beyV4CI90AAAAAADgIz3QDAAAAAOAghG4AAAAAAByE0A0AAAAAgIMQugEAAAAAcBBCNwAAAAAADkLoBgAAAADAQQjdAAAAAAA4CKEbAAAAAAAHIXQDAAAAAOAghG4AABoRwzA0YMAADR48+Lxt//rXvxQYGKijR486oTIAABomQjcAAI2IyWTSe++9p40bN+rf//63rT09PV1PPvmk3nzzTTVv3rxG39NisdTo8QAAqE8I3QAANDJRUVF6/fXX9fjjjys9PV2GYej+++/XoEGD1LVrVw0dOlS+vr4KCwvTn/70J50+fdq279KlS3XttdcqMDBQwcHBuvnmm3XgwAHb9oMHD8pkMul///uf+vfvL09PT3300UfOOE0AAOoEk2EYhrOLAAAAtS8hIUG5ubkaNWqUZsyYoR07dqhTp0564IEHdM8996i4uFjjx49XeXm5vvnmG0nS/PnzZTKZ1LlzZxUUFGjKlCk6ePCgtm7dKrPZrIMHDyomJkbR0dF65ZVX1LVrV3l6eqpZs2ZOPlsAAJyD0A0AQCN18uRJderUSdnZ2Zo/f75SU1O1bt06LVu2zNbn6NGjioqK0p49e9S2bdvzjnH69Gk1bdpU27dvV1xcnC10z5o1S4888khtng4AAHUSt5cDANBIhYaG6q9//as6dOighIQE/fTTT1q1apV8fX1tX+3bt5ck2y3k+/bt05133qnY2Fj5+/srOjpaknT48GG7Y3fr1q1WzwUAgLrK1dkFAAAA53F1dZWr69kfBwoKCjRixAi98MIL5/U7d3v4iBEj1LJlS73zzjuKiIiQ1WpVXFycysrK7Pr7+Pg4vngAAOoBQjcAAJAkXX311Zo/f76io6NtQfzXsrKytGfPHr3zzju67rrrJEnr16+v7TIBAKhXuL0cAABIkhITE5Wdna0777xTP/zwgw4cOKBly5bpvvvuU0VFhZo0aaLg4GC9/fbb2r9/v7755huNGzfO2WUDAFCnEboBAIAkKSIiQt9++60qKio0aNAgxcfHa+zYsQoMDJTZbJbZbNYnn3yizZs3Ky4uTo8++qheeuklZ5cNAECdxuzlAAAAAAA4CCPdAAAAAAA4CKEbAAAAAAAHIXQDAAAAAOAghG4AAAAAAByE0A0AAAAAgIMQugEAAAAAcBBCNwAAAAAADkLoBgAAAADAQQjdAAAAAAA4CKEbAAAAAAAHIXQDAAAAAOAghG4AAAAAABzk/wNSUAV/Mj3WhwAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'call_tool': {'messages': [FunctionMessage(content=\"python_repl response: Succesfully executed:\\n```python\\nimport matplotlib.pyplot as plt\\n\\n# Define the data\\nyears = [2020, 2021, 2022]\\ngdp_values = [1.99, 2.14, 2.2] # Trillion GBP\\n\\n# Create the line graph\\nplt.figure(figsize=(10, 5))\\nplt.plot(years, gdp_values, marker='o')\\n\\n# Labeling the graph\\nplt.title('UK GDP from 2020 to 2022')\\nplt.xlabel('Year')\\nplt.ylabel('GDP (Trillion GBP)')\\nplt.grid(True)\\nplt.xticks(years)\\nplt.tight_layout()\\n\\n# Display the graph\\nplt.show()\\n```\\nStdout: \", name='python_repl')]}}\n",
      "----\n",
      "{'Chart Generator': {'messages': [HumanMessage(content=\"Here is the line graph representing the UK's GDP from 2020 to 2022:\\n\\n[Please see the graph above]\\n\\nNote that the data for 2018 and 2019 is missing, and the graph only shows the years for which we have data. If you acquire the missing figures, you can manually add them to the graph to complete the five-year view.\", name='Chart Generator')], 'sender': 'Chart Generator'}}\n",
      "----\n",
      "{'Researcher': {'messages': [HumanMessage(content=\"FINAL ANSWER:\\n\\nHere is the line graph representing the UK's GDP from 2020 to 2022:\\n\\n[Please see the graph above]\\n\\nNote that the data for 2018 and 2019 is missing, and the graph only shows the years for which we have data. If you acquire the missing figures, you can manually add them to the graph to complete the five-year view.\", name='Researcher')], 'sender': 'Researcher'}}\n",
      "----\n",
      "{'__end__': {'messages': [HumanMessage(content=\"Fetch the UK's GDP over the past 5 years, then draw a line graph of it. Once you code it up, finish.\"), HumanMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"UK GDP data for the past 5 years\"}', 'name': 'tavily_search_results_json'}}, name='Researcher'), FunctionMessage(content=\"tavily_search_results_json response: [{'url': 'https://www.statista.com/topics/3795/gdp-of-the-uk/', 'content': 'Monthly GDP of the UK 2019-2023  Monthly GDP growth of the UK 2019-2023  Quarterly GDP growth of the UK 2019-2023  Quarterly GDP per capita in the UK 2019-2023Monthly index of gross domestic product in the United Kingdom from January 2019 to November 2023 (2019=100) GVA of the UK 2022, by sector GVA of the UK 2022, by sector Gross value added...'}, {'url': 'https://www.statista.com/topics/6500/the-british-economy/', 'content': 'Monthly GDP growth of the UK 2020-2023  Quarterly GDP growth of the UK 2015-2023  Monthly growth of gross domestic product in the United Kingdom from January 2020 to September 2023  Monthly GDP of the UK 1997-2023Economy The UK economy - Statistics & Facts United Kingdom The gross domestic product of the British economy was 2.23 trillion British pounds in 2022 and was the fifth- largest global...'}, {'url': 'https://www.ons.gov.uk/economy/grossdomesticproductgdp/bulletins/gdpmonthlyestimateuk/november2023', 'content': 'data from January 2022 to September 2023, as published in our\\\\xa0GDP quarterly national accounts, UK: July to September  Figure 1: UK GDP is estimated to have grown by 0.3% in November 2023  GDP monthly estimate, UK: November 2023  Source: Monthly GDP estimate from Office for National Statistics The main reasons for revisions in October 2023 are:Monthly GDP is estimated to have grown by 0.3% in November 2023, following an unrevised fall of 0.3% in October 2023. This release provides data for November 2023 and has revisions from January 2022 to September 2023, consistent with our Quarterly national accounts bulletin, published on 22 December 2023. October 2023 is also open for revision.'}, {'url': 'https://www.statista.com/statistics/375195/gdp-growth-forecast-uk/', 'content': 'Forecasted annual growth of gross domestic product in the United Kingdom from 2000 to 2028 Additional Information  GDP growth forecast for the UK 2000-2028 Weak economic growth throughout 2023  United Kingdom 2000 to 2028 *Forecast data Other statistics on the topicThe UK economy Economy  Economy Average annual earnings for full-time employees in the UK 1999-2023 Economy Inflation rate in the UK 1989-2023In 2022 the gross domestic product (GDP) of the United Kingdom grew by four percent but is expected to grow by just 0.6 percent in 2023, and 0.7 percent in 2024. More robust growth is...'}, {'url': 'https://www.ons.gov.uk/economy/grossdomesticproductgdp/bulletins/gdpmonthlyestimateuk/october2023', 'content': 'GDP monthly estimate, UK: October 2023  Figure 1: UK GDP is estimated to have fallen by 0.3% in October 2023  Monthly estimate of gross domestic product (GDP) containing constant price gross value added (GVA) data for the UK.  domestic product (GDP) in October 2023.1. Main points Monthly real gross domestic product (GDP) is estimated to have shown no growth in the three months to October 2023, compared with the three months to July 2023. Monthly GDP...'}]\", name='tavily_search_results_json'), HumanMessage(content=\"The search results provide information on the UK's GDP, including monthly and quarterly data from various years, but they do not provide a clear year-on-year GDP figure for each of the past five years. To graph the UK's GDP over the past five years, we need annual GDP figures for each year.\\n\\nI will attempt to extract the annual GDP figures mentioned in the search results and then graph them. However, please note that the information provided in the search results may be incomplete or not formatted in a way that allows for a straightforward extraction of annual GDP figures for each of the last five years. If necessary, I may need to perform additional searches to fill in any gaps.\\n\\nFrom the search results, we have the following relevant information regarding the UK's GDP:\\n\\n- The gross domestic product of the British economy was 2.23 trillion British pounds in 2022.\\n- In 2022, the gross domestic product (GDP) of the United Kingdom grew by four percent.\\n\\nUnfortunately, the search results do not provide explicit annual GDP figures for 2018, 2019, 2020, or 2021. Therefore, I will need to perform an additional search to find the missing GDP figures for these years. Let's proceed with that search.\", additional_kwargs={'function_call': {'arguments': '{\"query\":\"UK GDP 2018 2019 2020 2021\"}', 'name': 'tavily_search_results_json'}}, name='Researcher'), FunctionMessage(content='tavily_search_results_json response: [{\\'url\\': \\'https://www.statista.com/topics/3795/gdp-of-the-uk/\\', \\'content\\': \"GDP of the UK 2021, by country Gross domestic product of the United Kingdom in 2021, by country (in million GBP)  Monthly GDP of the UK 2019-2023  United Kingdom\\'s share of global gross domestic product (GDP) 2028  Quarterly GDP per capita in the UK 2019-2023In 2022, the gross domestic product of the United Kingdom amounted to approximately 2.2 trillion British pounds, compared with 2.14 trillion pounds in 2021, and 1.99 trillion in 2020. Although the ...\"}, {\\'url\\': \\'https://www.beta.ons.gov.uk/economy/grossdomesticproductgdp/compendium/unitedkingdomnationalaccountsthebluebook/2022/nationalaccountsataglance\\', \\'content\\': \"of UK GDP over 2020 and 2021  Figure 1: The UK economy increased by 7.5% in 2021, having seen the largest fall in over 300 years in 2020  accounts at a glance, UK National Accounts, The Blue Book: 2022  Figure 3: In 2021, nominal GDP in most of the G20 countries had recovered to its 2019 levelsIn 2021, the UK\\'s implied GDP deflator rose by 0.4%, the lowest among the developed countries shown (Figure 4). However, these comparisons are likely to reflect some of the measurement challenges over the coronavirus pandemic. Movements in the implied GDP deflator in 2020 and 2021 have been largely affected by the government consumption deflator.\"}, {\\'url\\': \\'https://www.ons.gov.uk/economy/grossdomesticproductgdp/bulletins/gdpmonthlyestimateuk/december2021\\', \\'content\\': \\'GDP monthly estimate, UK : December 2021  gross domestic product (GDP), UK.  data from January 2021 to November 2021. This is consistent with GDP first quarterly estimate, UK: October to December  on gross domestic product (GDP) in December 2021, with output of these services increasing by 51% and 19% respectively2. Monthly GDP. Monthly real gross domestic product (GDP) is estimated to have fallen by 0.2% in December 2021, compared with a 0.7% growth in November 2021 (revised down from 0.9% growth). This release includes revisions to the monthly data back to January 2021, consistent with the first quarterly estimate of GDP.\\'}, {\\'url\\': \\'https://www.beta.ons.gov.uk/economy/grossdomesticproductgdp/bulletins/gdpmonthlyestimateuk/september2021\\', \\'content\\': \\'GDP monthly estimate, UK: September 2021  2021, while detail on the quarterly path can also be found in GDP first quarterly estimate, UK: July to September 2021.  More detail on the quarterly path can also be found in GDP first quarterly estimate, UK: July to September 2021.  while detail on the quarterly path can also be found in GDP first quarterly estimate, UK: July to September 2021.Source: Office for National Statistics - GDP monthly estimate. Download this chart. Image .csv .xls. Monthly real gross domestic product (GDP) grew by 0.6% in September 2021, and follows a revised 0.2% growth in August 2021 (down from 0.4% growth) and a revised 0.2% fall in July 2021 (down from a 0.1% fall).\\'}, {\\'url\\': \\'https://www.ons.gov.uk/economy/grossdomesticproductgdp/bulletins/gdpmonthlyestimateuk/october2021\\', \\'content\\': \\'GDP monthly estimate, UK : October 2021  Figure 1: UK GDP is estimated to have grown by 0.1% in October 2021, but remains 0.5% below its pre-pandemic level  Monthly estimate of gross domestic product (GDP) containing constant price gross value added (GVA) data for the UK.  Source: Office for National Statistics – GDP monthly estimate NotesTable 1: UK GDP in October 2021 was 0.5% below its pre-pandemic level, however services has now returned to its pre-pandemic levelChange in output, percentage change, February 2020 to October 2021, UK. Source: Office for National Statistics - GDP monthly estimate. This table uses data from the output measure of GDP.\\'}]', name='tavily_search_results_json'), HumanMessage(content=\"Based on the search results, we can now extract some annual GDP figures for the UK:\\n\\n- In 2022, the gross domestic product of the United Kingdom amounted to approximately 2.2 trillion British pounds.\\n- In 2021, the gross domestic product of the United Kingdom was about 2.14 trillion British pounds.\\n- In 2020, the gross domestic product of the United Kingdom was about 1.99 trillion British pounds.\\n\\nUnfortunately, the search results still do not provide explicit figures for 2018 and 2019. To complete the dataset, we would need to perform another search or access historical economic data from a reliable source such as the Office for National Statistics (ONS) or an economic database. If additional searches are not possible, we may need to use these three data points to give a partial visualization of the trend. \\n\\nSince we cannot perform additional searches, I will provide the data points we have, and you will need to add the missing years' data manually if required:\\n\\n- 2020: 1.99 trillion GBP\\n- 2021: 2.14 trillion GBP\\n- 2022: 2.2 trillion GBP\\n\\nPlease note that the data for 2018 and 2019 is missing, and you would need to find these figures to complete the five-year view. With the data at hand, the line graph would only represent the years 2020 to 2022.\", name='Researcher'), HumanMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"code\":\"import matplotlib.pyplot as plt\\\\n\\\\n# Define the data\\\\nyears = [2020, 2021, 2022]\\\\ngdp_values = [1.99, 2.14, 2.2] # Trillion GBP\\\\n\\\\n# Create the line graph\\\\nplt.figure(figsize=(10, 5))\\\\nplt.plot(years, gdp_values, marker=\\'o\\')\\\\n\\\\n# Labeling the graph\\\\nplt.title(\\'UK GDP from 2020 to 2022\\')\\\\nplt.xlabel(\\'Year\\')\\\\nplt.ylabel(\\'GDP (Trillion GBP)\\')\\\\nplt.grid(True)\\\\nplt.xticks(years)\\\\nplt.tight_layout()\\\\n\\\\n# Display the graph\\\\nplt.show()\"}', 'name': 'python_repl'}}, name='Chart Generator'), FunctionMessage(content=\"python_repl response: Succesfully executed:\\n```python\\nimport matplotlib.pyplot as plt\\n\\n# Define the data\\nyears = [2020, 2021, 2022]\\ngdp_values = [1.99, 2.14, 2.2] # Trillion GBP\\n\\n# Create the line graph\\nplt.figure(figsize=(10, 5))\\nplt.plot(years, gdp_values, marker='o')\\n\\n# Labeling the graph\\nplt.title('UK GDP from 2020 to 2022')\\nplt.xlabel('Year')\\nplt.ylabel('GDP (Trillion GBP)')\\nplt.grid(True)\\nplt.xticks(years)\\nplt.tight_layout()\\n\\n# Display the graph\\nplt.show()\\n```\\nStdout: \", name='python_repl'), HumanMessage(content=\"Here is the line graph representing the UK's GDP from 2020 to 2022:\\n\\n[Please see the graph above]\\n\\nNote that the data for 2018 and 2019 is missing, and the graph only shows the years for which we have data. If you acquire the missing figures, you can manually add them to the graph to complete the five-year view.\", name='Chart Generator'), HumanMessage(content=\"FINAL ANSWER:\\n\\nHere is the line graph representing the UK's GDP from 2020 to 2022:\\n\\n[Please see the graph above]\\n\\nNote that the data for 2018 and 2019 is missing, and the graph only shows the years for which we have data. If you acquire the missing figures, you can manually add them to the graph to complete the five-year view.\", name='Researcher')], 'sender': 'Researcher'}}\n",
      "----\n"
     ]
    }
   ],
   "source": [
    "for s in graph.stream(\n",
    "    {\n",
    "        \"messages\": [\n",
    "            HumanMessage(\n",
    "                content=\"Fetch the UK's GDP over the past 5 years,\"\n",
    "                \" then draw a line graph of it.\"\n",
    "                \" Once you code it up, finish.\"\n",
    "            )\n",
    "        ],\n",
    "    },\n",
    "    # Maximum number of steps to take in the graph\n",
    "    {\"recursion_limit\": 150},\n",
    "):\n",
    "    print(s)\n",
    "    print(\"----\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "010fc36e-4116-4758-bcac-b02c7dcd405d",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
